/*
 * homedepotentry.c
 *
 *  Created on: Jun 15, 2011
 *      Author: peskanda
 *
 */

#ifndef HOMEDEPOTENTRY_C_
#define HOMEDEPOTENTRY_C_

#include "syscall.h"
#include <usercommon.h>
#include <userSharedDefinitions.h>
#include <userLocks.h>
#include <userHomedepot.h>
#include <userItem.h>
#include <userManager.h>
#include <userCashRegister.h>
#include <userClerk.h>
#include <userCustomer.h>
#include <userStockboy.h>
char *name;
int i;
int _cashRegisterLock;
int _cashRegisterCounter;
int cashRegisterId;
void CashRegisterThread(int line) {
    Acquire(_cashRegisterLock);
    cashRegisterId = _cashRegisterCounter;
    _cashRegisterCounter ++;
    Release(_cashRegisterLock);
    CashRegisterDoWork(cashRegisterId, cashRegisterId);
    Exit(0);
}
int _counterLock;
int _clerkCounter;
int clerkId;
void ClerkThread() {
    Acquire(_counterLock);
    clerkId = _clerkCounter;
    _clerkCounter ++;
    Release(_counterLock);
    ClerkGoToWork(clerkId);
    Exit(0);
}
int _stockBoyLock;
int stockBoyCounter;
int stockBoyId;
void StockBoyThread() {
    Acquire(_stockBoyLock);
    stockBoyId = stockBoyCounter;
    stockBoyCounter++;
    Release(_stockBoyLock);
    StockBoyDoWork(stockBoyId);
    Exit(0);
}
int _customerLock;
int customerCounter;
int customerID;
int randomVar;
int wantsToReturnItems;
void CustomerThread() {
    randomVar = Rand(5);
    wantsToReturnItems = (randomVar == 3);
    Acquire(_customerLock);
    customerID = customerCounter;
    customerCounter++;
    Release(_customerLock);
    DoShopping(customerID, wantsToReturnItems);
    Exit(0);
}
void ManagerThread() {
    ManagerDoWork();
    Exit(0);
}
int main() {
	printf("HomeDepot Simulation User Program\n");
	printLock = CreateLock("Printing Lock");
	InitializeLocks();
    printf_3("Number of Clerks = [", MAX_CLERKS, "]\n");
    printf_3("Number of StockBoys = [", MAX_STOCKBOYS, "]\n");
    printf_3("Number of CashRegisters = [", MAX_CLERKS, "]\n");
    printf_3("Number of Customers = [", MAXIMUM_OCCUPANCY, "]\n");
    printf_3("Number of Managers = [", 1, "]\n");
    printf_3("Number of Aisle = [", MAX_AISLES, "]\n");
    printf("  Items:\n");
    printf("    Number - Price\n");
    for (i = 0; i < MAX_ITEMS; i++) {
        printf_5("    [", i, "] - $[", theLocksInHomeDepotEntry.itemsInStore[i]._price, "]\n");
    }
    /*  Make Some Cash Registers */
    _cashRegisterLock = CreateLock("Cash Register Counter lock");
    _cashRegisterCounter = 0;
    for (i = 0; i < MAX_CLERKS; i++) {
        CallFork("Register", CashRegisterThread);
    }
    /*  Make Some Clerks */
    _counterLock = CreateLock("Clerk counter Lock");
    _clerkCounter = 0;
    for (i = 0; i < MAX_CLERKS; i++) {
        CallFork("Clerk", ClerkThread);
    }
    /* Make Some StockBoy */
    _stockBoyLock = CreateLock("StockBoy counter Lock");
    stockBoyCounter = 0;
    for (i = 0; i < MAX_STOCKBOYS; i++) {
        CallFork("StockBoy",StockBoyThread);
    }
    /* Make Some Customers  */
    _customerLock = CreateLock("Customer counter Lock");
    customerCounter = 0;
    for (i = 0; i < MAXIMUM_OCCUPANCY; i++) {
        CallFork("Customer", CustomerThread);
    }
    CallFork("Manager", ManagerThread);
    do {
        Acquire(theLocksInHomeDepotEntry._occupancyLock);
        if (theLocksInHomeDepotEntry._customersInStore == 0) {
            Release(theLocksInHomeDepotEntry._occupancyLock);
            return;
        } else {
            Release(theLocksInHomeDepotEntry._occupancyLock);
        }
        Yield();
    } while (TRUE);
    DestroyLock(printLock);
    Exit(0);
}

#endif
